package mote;

import java.util.StringTokenizer;

/**
 * NetworkPacket contains the information needed to exchange packets between the motes and base station
 * @author Khalid Alhokail, Vineet Gupta, Oren Melzer, David Schneider
 *
 */
class NetworkPacket
{
	public byte type; /* Cast to a packet_type */
	public byte destination;
	public byte source;
	public int data;

		
	public static final byte AM_HUB_ID = 1;
	public static final byte AM_ALL_NODES = 2;
	public static final byte AM_NODE_FIRST_ID = 10;
	public static final byte AM_COMPUTER_ID = 0;
	
	public static final byte LIGHT_SENSOR = 0;
	public static final byte LED_COMMAND = 1;
	public static final byte SET_SAMPLING_INTERVAL = 2;
	public static final byte SET_LIGHT_REPORT_THRESHOLD = 3;
	public static final byte BAD_PACKET = 9;

	/**
	 * Creates a NetworkPacket with the specified settings.
	 * @param type			The type of the packet as a byte. View the static 
	 * 						final values for meanings
	 * @param destination	The destination that the packet was intended to go to
	 * @param source		The source that the packet came from
	 * @param data			The data contained in the packet
	 */
	public NetworkPacket(byte type, byte destination, byte source, int data){
		this.type = type;
		this.destination = destination;
		this.source = source;
		this.data = data;
	}
		
	/**
	 * Creates a NetworkPacket with the specified settings. A more general 
	 * overloading of the constructor.
	 * @param type			The type of the packet as a byte. View the static 
	 * 						final values for meanings
	 * @param destination	The destination that the packet was intended to go to
	 * @param source		The source that the packet came from
	 * @param data			The data contained in the packet
	 */
	public NetworkPacket(int type, int destination, int source, int data){
		this((byte)type,(byte)destination,(byte)source,data);
	}

	/**
	 * A default constructor. All packet values default to 0.
	 *
	 */
	public NetworkPacket(){
		this(0,0,0,0);
	}
	
	/**
	 * Parses an packet from a given string. If the packet is incomplete, the 
	 * parsing sets the type to BAD_PACKET. The parsing defaults other values 
	 * to 0 if they are not found.
	 * @param input The String from which the packet should be parsed from. 
	 * 				The String should be in the form: <t>type<d>destination<s>source<p>data</>
	 */
	public NetworkPacket(String input){
		StringTokenizer tokens = new StringTokenizer(input, 
					"<>");
		type = BAD_PACKET;
		destination = 0; 
		source = 0;
		data = 0;
		String cur = null;
		String last = null;
		while(tokens.hasMoreTokens()){
			last = cur;
			cur = tokens.nextToken();
			if(last!=null){
				if(last.equals("t"))
					type = (byte)(new Integer(cur)).intValue();
				if(last.equals("d"))
					destination = (byte)(new Integer(cur)).intValue();
				if(last.equals("s"))
					source = (byte)(new Integer(cur)).intValue();
				if(last.equals("p"))
					data = (new Integer(cur)).intValue();
			}
		}
	}
	
	/**
	 * Returns a String representation of the packet. The String representation
	 * is the same as for input in NetworkPacket(String input).
	 */
	public String toString(){
		return    "<t>" + type
			+ "<d>" + destination
			+ "<s>" + source
			+ "<p>" + data
			+ "</>";
	}
	
	/**
	 * Returns the value of the network packet as an array of bytes
	 * @return Network Packet as an array of bytes
	 */
	public byte[] tinyOSNetworkPacket(){
		byte result[] = {(byte)type, (byte) destination, (byte)source, (byte)(data >> 8), (byte)data};
		return result;
	}	
}
